package com.bryantkobe.myspringcode.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @description: 日志切面
 * @author: alienwarezzl
 * @date: 2025/9/21
 */
@Component
@Aspect
public class LoggingAspect {

    private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);

    //定义一个切点：拦截所有controller层公共方法
    @Pointcut("execution(public * com.bryantkobe.myspringcode.controller..*.*(..)))")
    public void controllerPointcut() {}

    //环绕通知：记录方法执行时间、参数和结果
    @Around("controllerPointcut()")
    public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        String className = pjp.getTarget().getClass().getSimpleName();
        String methodName = pjp.getSignature().getName();
        Object[] args = pjp.getArgs();

        //记录方法开始日志（此时MDC中的traceId已被过滤器设置）
        log.info(">> {},{}() - Args: {}", className, methodName, Arrays.toString(args));

        try {
            Object result = pjp.proceed();
            long executionTime = System.currentTimeMillis() - startTime;

            //记录方法结束日志
            log.info(">> {},{}() - Execution Time: {}ms - Result: {}", className, methodName, executionTime,result);
            return result;
        }catch (Throwable throwable){
            long exectutionTime = System.currentTimeMillis() - startTime;
            log.error("<< {}.{}() - Execution Time: {}ms - Throwable: {}", className, methodName, exectutionTime,throwable.getMessage(),throwable);
            throw throwable;
        }
    }
}
